package middleware

import (
	"github.com/gin-gonic/gin" // 导入Gin框架核心包，用于处理HTTP请求和响应
	"net/http"                 // 导入HTTP包，提供标准HTTP状态码定义
)

// GlobalErrorHandler 全局错误处理中间件
// 功能：统一捕获和处理应用中所有错误，确保API返回格式一致
// 工作原理：在请求处理链的最后执行，收集并处理前面环节产生的所有错误
func GlobalErrorHandler() gin.HandlerFunc {
	// 返回符合Gin框架规范的中间件函数
	return func(c *gin.Context) {
		// 1. 先执行后续的中间件和路由处理函数
		// c.Next()会暂停当前中间件，跳转到下一个处理环节
		// 当后续所有处理完成后，才会回到这里继续执行
		c.Next()

		// 2. 处理自定义业务错误（通过c.Set("error", ...)设置的错误）
		// 这类错误通常是业务逻辑中主动设置的可预期错误（如未登录、参数错误等）
		if err, exists := c.Get("error"); exists {
			// 将接口类型的错误转换为字符串类型
			// 类型断言：检查err是否为string类型，ok为true表示转换成功
			errMsg, ok := err.(string)
			if !ok {
				// 若转换失败（错误不是字符串类型），使用默认错误信息
				errMsg = "未知错误"
			}

			// 返回统一格式的JSON错误响应
			// http.StatusUnauthorized：HTTP状态码401（未授权）
			// 响应体包含code（业务错误码）和msg（错误描述）
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,    // 业务错误码，与HTTP状态码保持一致便于理解
				"msg":  errMsg, // 具体错误信息，用于前端展示给用户
			})
			return // 错误处理完毕，终止后续流程
		}

		// 3. 处理框架自动捕获的错误（通过c.Error()添加的错误）
		// 这类错误通常是系统级错误（如数据库连接失败、JSON解析错误等）
		// 先检查错误列表是否存在且不为空（避免空指针异常）
		if c.Errors != nil && len(c.Errors) > 0 {
			// 获取错误列表中的第一个错误（通常是根源错误）
			firstErr := c.Errors[0]

			// 返回服务器内部错误响应
			// http.StatusInternalServerError：HTTP状态码500（服务器内部错误）
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": 500, // 业务错误码，标识服务器端错误
				// 错误信息包含具体错误详情，便于开发调试
				// 生产环境可考虑简化信息（如仅返回"服务器内部错误"）
				"msg": "服务器内部错误：" + firstErr.Error(),
			})
			return // 错误处理完毕，终止后续流程
		}

		// 4. 若没有错误，则继续执行（由Gin框架返回正常响应）
	}
}
